package com.example.gulimall.ware.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.constant.WareConstant;
import com.example.common.exception.RRException;
import com.example.common.utils.PageUtils;
import com.example.common.utils.Query;
import com.example.gulimall.ware.dao.PurchaseDao;
import com.example.gulimall.ware.entity.PurchaseDetailEntity;
import com.example.gulimall.ware.entity.PurchaseEntity;
import com.example.gulimall.ware.entity.WareSkuEntity;
import com.example.gulimall.ware.service.PurchaseDetailService;
import com.example.gulimall.ware.service.PurchaseService;
import com.example.gulimall.ware.service.WareSkuService;
import com.example.gulimall.ware.vo.MergeVo;
import com.example.gulimall.ware.vo.PurchaseDoneItemsVo;
import com.example.gulimall.ware.vo.PurchaseDoneVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired private PurchaseDetailService purchaseDetailService;
    @Autowired private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPageUnReceive(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                Wrappers.<PurchaseEntity>lambdaQuery()
                        .eq(PurchaseEntity::getStatus, 0).or().eq(PurchaseEntity::getStatus, 0)

        );
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                Wrappers.lambdaQuery()

        );
        return new PageUtils(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void merge(MergeVo vo) {

        Long purchaseId = vo.getPurchaseId();

        if (Objects.isNull(purchaseId)) {
            PurchaseEntity purchaseEntity = new PurchaseEntity()
                    .setStatus(WareConstant.PurchaseStatus.CREATED.getCode())
                    .setCreateTime(new Date())
                    .setUpdateTime(new Date());
            this.save(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }

        PurchaseEntity purchaseEntity = this.baseMapper.selectById(purchaseId);
        // 当事务未提交的情况下是查不到数据的
        if (Objects.nonNull(purchaseEntity)) {
            Integer status = purchaseEntity.getStatus();
            if (status != WareConstant.PurchaseStatus.CREATED.getCode()
                    || status != WareConstant.PurchaseStatus.ASSIGNED.getCode()) {
                throw new RRException("不能操作已分配的采购单!");
            }
        }


        List<Long> items = vo.getItems();
        Long finalPurchaseId = purchaseId;

        List<PurchaseDetailEntity> entityList = items.stream().map(
                a -> new PurchaseDetailEntity()
                        .setStatus(WareConstant.PurchaseDetailsStatus.ASSIGNED.getCode())
                        .setId(a)
                        .setPurchaseId(finalPurchaseId)
        ).collect(Collectors.toList());

        purchaseDetailService.updateBatchById(entityList);

        this.baseMapper.update(
                null,
                Wrappers.<PurchaseEntity>lambdaUpdate()
                        .set(PurchaseEntity::getUpdateTime, new Date())
                        .eq(PurchaseEntity::getId, purchaseId)
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void received(List<Long> ids) {
        List<PurchaseEntity> purchaseEntities = this.baseMapper.selectList(
                Wrappers.<PurchaseEntity>lambdaQuery()
                        .in(PurchaseEntity::getId, ids)
        ).stream()
                .filter(
                        a -> a.getStatus() == WareConstant.PurchaseStatus.CREATED.getCode()
                                || a.getStatus() == WareConstant.PurchaseStatus.ASSIGNED.getCode()
                ).peek(
                        b -> {
                            b.setStatus(WareConstant.PurchaseStatus.RECEIVE.getCode());
                            b.setUpdateTime(new Date());
                        }
                ).collect(Collectors.toList());

        this.updateBatchById(purchaseEntities);
        this.purchaseDetailService.updateDetailByPurchaseIds(
                purchaseEntities.stream().map(PurchaseEntity::getId).collect(Collectors.toSet())
        );
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void done(PurchaseDoneVo vo) {

        // 改变采购项状态
        boolean flag = true;
        // 采购项集合
        List<PurchaseDetailEntity> detailEntities = new ArrayList<>();
        // 存储采购成功的采购项，用于入库操作
        List<WareSkuEntity> success = new ArrayList<>();


        for (PurchaseDoneItemsVo item : vo.getItems()) {
            PurchaseDetailEntity entity = new PurchaseDetailEntity();
            if (item.getStatus() == WareConstant.PurchaseStatus.ERROR.getCode()) {
                entity.setStatus(item.getStatus());
                flag = false;
            } else {
                entity.setStatus(WareConstant.PurchaseStatus.FINISHED.getCode());
                // 入库操作
                PurchaseDetailEntity purchaseDetailEntity = this.purchaseDetailService.getById(item.getItemId());
                success.add(
                        new WareSkuEntity()
                        .setSkuId(purchaseDetailEntity.getSkuId())
                        .setWareId(purchaseDetailEntity.getWareId())
                        .setStock(purchaseDetailEntity.getSkuNum())
                );
            }

            entity.setId(item.getItemId());
            detailEntities.add(entity);
        }

        this.purchaseDetailService.updateBatchById(detailEntities);

        //改变采购单状态
        this.baseMapper.update(
                null,
                Wrappers.<PurchaseEntity>lambdaUpdate()
                        .set(
                                PurchaseEntity::getStatus, flag
                                        ? WareConstant.PurchaseStatus.ERROR.getCode()
                                        : WareConstant.PurchaseStatus.FINISHED.getCode()
                        )
                        .set(PurchaseEntity::getUpdateTime, new Date())
                        .eq(PurchaseEntity::getId, vo.getId())
        );


        // 将采购成功的进行入库, 从采购成功的结果中获取
        this.wareSkuService.updateBatchByCondition(success);

    }

}